package top.lingkang.mm.transaction;

import lombok.extern.slf4j.Slf4j;
import top.lingkang.mm.error.MagicException;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * 事务管理，在spring体系中不生效。使用方式：
 * <pre>
 * {@code
 * TransactionManage.beginTransaction();
 * try {
 *     mapperManage.insert(entity, false);
 *     // 提交事务
 *     TransactionManage.commit();
 * } catch (Exception e) {
 *     // 回滚事务
 *     TransactionManage.rollback();
 *     throw e;
 * }
 * }
 * </pre>
 *
 * @Author lingkang
 * @Date 2024/2/29 14:08
 */
@Slf4j
public final class TransactionManage {
    private static final ThreadLocal<Connection> tm = new ThreadLocal<>();
    private static final ThreadLocal<Boolean> openTran = ThreadLocal.withInitial(() -> false);

    public static Connection getConnection(DataSource dataSource) throws SQLException {
        if (openTran.get()) {
            Connection connection = tm.get();
            if (connection != null)
                return connection;
            connection = dataSource.getConnection();
            connection.setAutoCommit(false);
            tm.set(connection);
            return connection;
        }
        return dataSource.getConnection();
    }

    public static void beginTransaction() {
        if (openTran.get()) {
            log.warn("事务已经开启了");
            return;
        }
        openTran.set(true);
        log.debug("启用事务");
    }

    public static boolean isTransaction() {
        return openTran.get();
    }

    public static void commit() {
        if (!isTransaction())
            return;
        Connection connection = tm.get();
        if (connection == null) {
            openTran.set(false);
            return;
        }
        try {
            connection.commit();
            connection.close();
            log.debug("提交事务成功");
            tm.remove();
            openTran.set(false);
            log.debug("关闭连接");
        } catch (SQLException e) {
            throw new MagicException("提交事务失败", e);
        }
    }

    public static void rollback() {
        if (!isTransaction())
            return;
        Connection connection = tm.get();
        if (connection == null) {
            openTran.set(false);
            return;
        }
        try {
            connection.rollback();
            connection.close();
            log.debug("回滚事务成功");
            tm.remove();
            openTran.set(false);
            log.debug("关闭连接");
        } catch (SQLException e) {
            throw new MagicException("回滚事务失败", e);
        }
    }


}
